#include "Character.h"

Character::Character()
	:m_moveIntent(NO_MOVE)
{

}

Character::~Character()
{

}

void Character::handleInput(int a_input)
{
	switch(a_input)	//Handle movement
	{
	case 'w':
	case UP_ARROW:
		m_moveIntent = NORTH;
		break;
	case 'a':
	case LEFT_ARROW:
		m_moveIntent = WEST;
		break;
	case 's':
	case DOWN_ARROW:
		m_moveIntent = SOUTH;
		break;
	case 'd':
	case RIGHT_ARROW:
		m_moveIntent = EAST;
		break;
	default:
		m_moveIntent = NO_MOVE;
		break;
	}
}

void Character::update()
{
	//Store the character's current location
	int prevX = m_Location.getX(); int prevY = m_Location.getY();

	//Try to move where it wants
	switch(m_moveIntent)	
	{
	case NO_MOVE:

		break;
	case NORTH:
		move(NORTH, 1);
		break;
	case SOUTH:
		move(SOUTH, 1);
		break;
	case EAST:
		move(EAST, 1);
		break;
	case WEST:
		move(WEST, 1);
		break;
	default:
		printf("Something broke:  Character::update()");
		break;
	}
	//Stop moving
	m_moveIntent = NO_MOVE;
	//if the position has changed, request a redraw of the game
	if (m_Location.getX() != prevX || m_Location.getY() != prevY)
	{
		//Redraw the map & character
		m_Map->redrawAt(prevX, prevY);
	}
	this->redraw();
}

void Character::draw()
{
	if (m_redrawEntity)
	{
		//Move the console output to the right xy location
		COORD temp = {m_Location.getX(), m_Location.getY()};
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), temp);
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), m_color);
		//Draw the character
		putchar(m_icon);
		//Unset the draw flag
		m_redrawEntity = false;
	}
}

void Character::redraw()
{
	m_redrawEntity = true;
}

void Character::move(DIRECTION a_direction, int a_distance)
{
	//Go ahead and move
	switch(a_direction)
	{
	case NORTH:
		m_Location.setY(m_Location.getY() - a_distance);
		break;
	case SOUTH:
		m_Location.setY(m_Location.getY() + a_distance);
		break;
	case EAST:
		m_Location.setX(m_Location.getX() + a_distance);
		break;
	case WEST:
		m_Location.setX(m_Location.getX() - a_distance);
		break;
	case UP:

		break;
	case DOWN:

		break;
	default:

		break;
	}
	//Ensure that the player is still in maps maximum/minimum boundaries
	if (m_Location.getX() < 0)
		m_Location.setX(0);
	if (m_Location.getY() < 0)
		m_Location.setY(0);
	if (m_Location.getX() >= MAP_DEFAULT_WIDTH)
		m_Location.setX(MAP_DEFAULT_WIDTH-1);
	if (m_Location.getY() >= MAP_DEFAULT_HEIGHT)
		m_Location.setY(MAP_DEFAULT_HEIGHT-1);
	//Handle any wall/obstacle collision
	if (m_Map->getLocationAt(m_Location.getX(), m_Location.getY()) != '.'  &&  m_Map->getLocationAt(m_Location.getX(), m_Location.getY()) != '*')
	{
		switch(a_direction)
		{
		case NORTH:
			move(SOUTH, 1);
			break;
		case SOUTH:
			move(NORTH, 1);
			break;
		case EAST:
			move(WEST, 1);
			break;
		case WEST:
			move (EAST, 1);
			break;
		case UP:

			break;
		case DOWN:

			break;
		default:

			break;
		}
	}
	//Update Map Visibility
	m_Map->updateMap(m_Location.getX(), m_Location.getY());
}

void Character::place(int a_x, int a_y)
{
	m_Location.setX(a_x);
	m_Location.setY(a_y);
	//Boundry checking
	if (m_Location.getX() < 0)
		m_Location.setX(0);
	if (m_Location.getX() > MAP_DEFAULT_WIDTH)
		m_Location.setX(MAP_DEFAULT_WIDTH);
	if (m_Location.getY() < 0)
		m_Location.setY(0);
	if (m_Location.getY() > MAP_DEFAULT_HEIGHT)
		m_Location.setY(MAP_DEFAULT_HEIGHT);
}

void Character::spawn()
{
	Location temp;
	do
	{
		temp.setX(rand() % MAP_DEFAULT_WIDTH);
		temp.setY(rand() % MAP_DEFAULT_HEIGHT);
	}while(m_Map->getLocationAt(temp.getX(), temp.getY()) != '.');

	this->place(temp.getX(), temp.getY());
	m_Map->updateMap(temp.getX(), temp.getY());
}